class SceneSnake extends Scene {
  constructor(game) {
    super(game)

    this.headImgs = {
      left: new Spirit('head-left.png'),
      right: new Spirit('head-right.png'),
      up: new Spirit('head-up.png'),
      down: new Spirit('head-down.png'),
    }

    // 蛇
    this.snake = new Snake()
    this.head = this.headImgs.right
    this.body = new Spirit('body.webp')
    // 食物
    this.food = { x: 10, y: 10, w: 20, h: 20 }

    // 网格大小
    this.gridSize = 20
    // 行数
    this.rowNumbers = game.canvas.height / this.gridSize
    // 每隔30帧移动一次
    this.frames = 30

    this.score = 0
    this.gameover = false


    this.label = new Label('游戏结束!')
    this.label.x = 200
    this.label.y = 300
    this.label.color = '#f00'

    this.setup()
  }


  setup() {
    const s = this.snake

    window.addEventListener('keydown', (event) => {
      let k = event.key
      if (k === 'a') {
        s.turnLeft()
      } else if (k === 'd') {
        s.turnRight()
      } else if (k === 'w') {
        s.turnUp()
      } else if (k === 's') {
        s.turnDown()
      }

      this.updateHead()
    })
  }

  update() {
    if (this.gameover) {
      console.log('over');
      return
    }

    if (this.frames === 0) {
      this.frames = 30
      this.check()
      this.snake.move()
      let isEat = this.eating()
      if (isEat) {
        this.makeFood()
        this.score += 10
      }
    }
    this.frames--
  }

  updateHead() {
    let dir = this.snake.dir
    this.head = this.headImgs[dir]
  }

  check() {
    const body = this.snake.body
    const head = body[body.length - 1]
    let xOut = head.x > this.rowNumbers - 2 || head.x < 1
    let yOut = head.y > this.rowNumbers - 2 || head.y < 1
    this.gameover = xOut || yOut || this.snake.isEatSelf()
    return this.gameover
  }

  draw() {
    let ctx = this.game.context
    // super.draw()
    this.drawGrid(ctx)
    this.drawSnake(ctx)
    this.drawFood(ctx)
    this.drawScore(ctx)

    if (this.gameover) {
      this.label.draw(ctx)
    }
  }

  eating() {
    let first = this.snake.body.at(0)
    let last = this.snake.body.at(-1)
    if (last.x === this.food.x && last.y === this.food.y) {
      this.snake.body.unshift(first)
      console.log('吃')
      return true
    }
    return false
  }

  makeFood() {
    const food = this.food
    // generate
    let x = Math.round(Math.random() * this.rowNumbers)
    let y = Math.round(Math.random() * this.rowNumbers)
    const inSnake = this.snake.body.some(s => s.x === x && s.y === y)
    if (inSnake) {
      this.makeFood()
      return
    }
    food.x = x
    food.y = y
  }

  drawSnake(ctx) {
    for (let i = 0, len = this.snake.body.length; i < len; i++) {
      const item = this.snake.body[i];
      let x = item.x * this.gridSize
      let y = item.y * this.gridSize
      let w = this.gridSize
      let h = this.gridSize

      this.body.x = x
      this.body.y = y
      this.body.w = w
      this.body.h = h

      this.head.x = x
      this.head.y = y
      this.head.w = w
      this.head.h = h

      if (i === len - 1) {
        this.head.draw(ctx)
      } else {
        this.body.draw(ctx)
      }

    }

  }

  drawFood(ctx) {
    const { x, y, w, h } = this.food
    ctx.save()
    ctx.fillStyle = '#ff9100'
    ctx.fillRect(x * this.gridSize, y * this.gridSize, w, h)
    ctx.restore()
  }

  drawScore(ctx) {
    ctx.save()
    ctx.font = '14px Arial'
    ctx.fillStyle = '#fa25d6'
    ctx.fillText('得分：' + this.score, 10, 20)
    ctx.restore()
  }

  drawGrid(ctx) {

    const { gridSize, rowNumbers, game } = this

    ctx.save()
    ctx.strokeStyle = '#ccc'

    for (let i = 1; i < rowNumbers; i++) {
      ctx.beginPath()
      ctx.moveTo(0, i * gridSize)
      ctx.lineTo(game.canvas.width, i * gridSize + 0.5)
      ctx.stroke()
      ctx.beginPath()
      ctx.moveTo(i * gridSize, 0)
      ctx.lineTo(i * gridSize + 0.5, game.canvas.height)
      ctx.stroke()
    }
    ctx.restore()
  }
}
